home *** CD-ROM | disk | FTP | other *** search
- /* Read a specified Maple WorkSheet, parse it,
- * and feed it to the Maple computation engine
- *
- * Copyright © Joe Veazey 1996
- * Copyright © Thore Böckelmann 1997,1998
- * All rights reserved
- * $VER: ReadWorkSheet.rexx 2.1 (4.3.98)
- *
- * History:
- * 1.0: first release by Joe Veazey
- * 2.0: added support for MapleV R4 worksheets
- * 2.1: fixed problems with R4 worksheets from Intel systems
- * added support for missing region markers
- * R4 Hyperlinks (not supported by R3) are now surrounded by "_" and treated as comments
- */
-
- options results
- options failat 30
-
- signal on syntax
- signal on novalue
-
- LexState.CurrentLine = ""
- LexState.CurrentCol = 1
- LexState.UnGetQueue = ""
- LexState.LineNumber = 0
-
- ParseState.UnGetQueue = ""
- ParseState.UnGetTypeQueue = ""
- ParseState.CurrentToken = ""
- ParseState.TokenValue = ""
- ParseState.TokenType = ""
- ParseState.Indent = 0
- ParseState.SemanticText = ""
-
- parse arg FileName " " Options
- parse upper value " "Options" ." with " TRACE" +1 TraceFlag " "
- parse upper value " "Options" ." with " TOKENTRACE" +1 TokenTraceFlag " "
- parse upper value " "Options" ." with " PARSETRACE" +1 ParseTraceFlag " "
- parse upper value " "Options" ." with " LIST" +1 LexListFlag " "
- parse upper value " "Options" ." with " NOMAPLE" +1 NoMapleFlag " "
- parse upper value " "Options" ." with " ASYNC" +1 AsyncFlag " "
-
- if TraceFlag ~= "" then trace results
-
- if TokenTraceFlag ~= "" ,
- then ParseState.TokenTrace = 1
- else ParseState.TokenTrace = 0
-
- if ParseTraceFlag ~= "" ,
- then ParseState.ParseTrace = 1
- else ParseState.ParseTrace = 0
-
- if LexListFlag ~= "" ,
- then LexState.List = 1
- else LexState.List = 0
-
- if NoMapleFlag ~= "" ,
- then ExecuteState.CallMaple = 0
- else ExecuteState.CallMaple = 1
-
- if AsyncFlag ~= "" ,
- then ExecuteState.Async = 1
- else ExecuteState.Async = 0
-
- if FileName == "?" | FileName == "" ,
- then do
- say "FORMAT"
- say " ReadWorkSheet [Filename | ?] [TRACE] [TOKENTRACE] [PARSETRACE]"
- say " [LIST] [NOMAPLE] [ASYNC]"
- say ""
- say "TEMPLATE"
- say " Filename,TRACE/S,TOKENTRACE/S,PARSETRACE/S,LIST/S,NOMAPLE/S,ASYNC/S"
- say ""
- say "PURPOSE"
- say " Allow Amiga MapleV R3 to read worksheets produced by other MapleV versions"
- say " and platforms"
- say ""
- say "SPECIFICATION"
- say " ReadWorkSheet.rexx is an ARexx script to read and execute MapleV worksheet"
- say " produced by any platform or MapleV version. Text regions and input regions"
- say " will be passed to the Amiga MapleV engine to be processed."
- say ""
- say " The filename can be replaced with ? to obtain this help output."
- say ""
- say " The TRACE keyword causes an ARexx 'Trace Results' to be issued and is meant"
- say " for debugging ReadWorkSheet itself."
- say ""
- say " TOKENTRACE will display each and every token from the worksheet as it is"
- say " read. Also used for debugging or checking out the syntax of a new worksheet"
- say " format."
- say ""
- say " PARSETRACE traces the entry and exit of all parse subroutines, with"
- say " indentation. Various significant data from the worksheet will also be"
- say " displayed."
- say ""
- say " LIST will list the contents of the entire worksheet to STDOUT, as it is"
- say " parsed."
- say ""
- say " NOMAPLE will parse only, and can be used without starting up MapleV first."
- say ""
- say " ASYNC will allow the parse to continue asynchronously with MapleV's"
- say " execution. Otherwise, the parse will wait for MapleV to stop calculating"
- say " before sending it any input string that requires computation."
- say ""
- say "IMPLEMENTATION"
- say " ReadWorkSheet.rexx uses recursive descent parsing to parse the MapleV"
- say " worksheet. The syntax of a MapleV Worksheet is described in psuedo-BNF"
- say " format in comments within the program. There are also several useful"
- say " subroutines for parsing (GetChar, UnGetChar, GetToken, UnGetToken,"
- say " ParseTrace, ParseTraceEntry, ParseTraceExit, and TokenTrace."
- say ""
- say " Unfortunately, ReadWorkSheet.rexx can run very slowly, as it must skip over"
- say " all of the worksheet text that represents graphics data, typeset math"
- say " expressions, or MapleV output."
- say ""
- say " The syntax of MapleV worksheets was derived by careful examination of"
- say " numerous MapleV worksheets, many of which were obtained from the Net."
- say ""
- say " This program was motivated by the fact that Amiga MapleV on my machine, in"
- say " my environment, gurus when fed a non-Amiga MapleV worksheet."
- say ""
- say " If you encounter a valid MapleV worksheet that causes ReadWorkSheet.rexx to"
- say " report a syntax error, please lha it, uuencode that, and email the result"
- say " to me at: tboeckel@uni-paderborn.de"
- say ""
- say " I also welcome any other comments, bug reports, or suggestions. I am also"
- say " interested in any deeper secrets about Maple worksheet structures,"
- say " especially the DAG, DIB, and AGR regions, and the meanings of the various"
- say " flags and numeric values found in a Maple worksheet."
- say ""
- say "AUTHOR"
- say " Joe Veazey: 73227.2656@compuserve.com (first version)"
- say " Thore Boeckelmann: tboeckel@uni-paderborn.de"
- say ""
- exit 5
- end
-
- WsIn = 'WsIn'
- if ~open(WsIn, FileName, 'R') ,
- then do
- Say "Can't open file" FileName
- return 20
- end
-
- PortName = "MAPLE1"
- address value PortName
-
- call GetToken() /* Prime the Pump */
-
- myRC = 0
- if WorkSheet() , /* Parse the entire worksheet */
- then say "WorkSheet successful"
- else do
- say "WorkSheet failed"
- myRC = 10
- end
-
- call close(WsIn)
- exit myRC
-
- /* Panic if a syntax error occurs */
- syntax: say "*** Syntax Error ***"
- say LexState.CurrentLine
- say right("",LexState.CurrentCol-1,"-") ,
- || "|<--- Column("LexState.CurrentCol") Line" LexState.LineNumber
- say ""
- say "Token <"ParseState.CurrentToken"> Type <"ParseState.TokenType"> Failed to match"
- say "SIGL="sigl"; SourceLine=<"sourceline(sigl)">"
- exit 10
-
-
- /*
- * WorkSheet := "{" VersionSpec "}"
- * ( "{" GlobalSpec "}"
- * "{" ScpRegion | FontRegion | "END" "}" ... ) |
- * ( "{" UStyleTabRegion "}"
- * "{" SectionRegion "}" ...
- * "{" MarkSection "}"
- * "{" ViewOptsSection "}" )
- * /*EOF*/ ;
- */
- WorkSheet: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchOperator("{") then return 0
- call ParseTraceEntry("WorkSheet")
- if ~VersionSpec() then signal syntax /* FALSE means not matched */
- if ~MatchOperator("}") then signal syntax
-
- if ~MatchOperator("{") then signal syntax
- if GlobalSpec() then mapleVer=3
- else if UStyleTabRegion() then mapleVer=4
- else signal syntax /* 10 means error */
- if ~MatchOperator("}") then signal syntax
-
- if mapleVer=3 then do /* MapleV R3 Worksheet */
- say "This is an MapleV R3 Worksheet"
- do forever
- if ~MatchOperator("{") then signal syntax
-
- if ~ScpRegion() ,
- then if ~FontRegion() ,
- then if ~MatchKeyWord("END")then signal syntax
- else leave
-
- if ~MatchOperator("}") then signal syntax
- end
-
- if ~MatchOperator("}") then signal syntax /* Catch "}" from END */
- if ~MatchEOF() then signal syntax
- end
- else if mapleVer=4 then do /* MapleV R4+ Worksheet */
- say "This is an MapleV R4 Worksheet"
- do forever
- if MatchEOF() then leave
- if ~MatchOperator("{") then signal syntax
-
- if ~SectionRegion() ,
- then if ~MarkSection() ,
- then if ~ViewOptsSection() then signal syntax
- else leave
-
- if ~MatchOperator("}") then signal syntax
- end
- end
-
- call ParseTraceExit("WorkSheet")
- return 1 /* TRUE (1) means parsed OK */
-
-
- /*
- * VersionSpec := "VERSION" VersionNumA VersionNumB
- * SystemString VersionString ;
- */
- VersionSpec: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("VERSION") then return 0
- call ParseTraceEntry("VersionSpec")
- if ~MatchNumber() then signal syntax /* VersionNumA */
- /* VersionNumA = ParseState.TokenValue */
- if ~MatchNumber() then signal syntax /* VersionNumB */
- /* VersionNumB = ParseState.TokenValue */
- if ~MatchStringQQ() then signal syntax /* SystemString */
- SystemString = ParseState.TokenValue
- if ~MatchStringQQ() then signal syntax /* VersionString */
- /* VersionString = ParseState.TokenValue */
- call ParseTrace("SystemString =" SystemString)
- call ParseTraceExit("VersionSpec")
- return 1 /* TRUE (1) means parsed OK */
-
-
- /*
- * GlobalSpec := "GLOBALS" GlobalNumA GlobalNumB ;
- */
- GlobalSpec: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("GLOBALS") then return 0
- call ParseTraceEntry("GlobalSpec")
- if ~MatchNumber() then signal syntax; /* GlobalNumA */
- if ~MatchNumber() then signal syntax; /* GlobalNumB */
- call ParseTraceExit("GlobalSpec")
- return 1
-
-
- /*
- * UStyleTabRegion := "USTYLETAB" "{" CStyleSpec | PStyleRegion "}";
- */
- UStyleTabRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("USTYLETAB") then return 0
- call ParseTraceEntry("UStyleTabRegion")
- do forever
- if ~MatchOperator("{") then leave /* signal syntax */
- if ~CStyleSpec() ,
- then if ~PStyleRegion() then signal syntax
- if ~MatchOperator("}") then signal syntax
- end
- call ParseTraceExit("UStyleTabRegion")
- return 1 /* TRUE (1) means parsed OK */
-
-
- /* CStyleSpec := "CSTYLE" StyleName Num1 Num2 FontName
- * NumF1 NumF2 NumF3 NumF4 NumF5 NumF6 NumF7
- * NumF8 NumF9 NumF10 NumF11 NumF12 NumF13 NumF14 NumF15;
- */
- CStyleSpec: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("CSTYLE") then return 0
- call ParseTraceEntry("CStyleSpec")
- if ~MatchStringQQ() then signal syntax; /* StyleName */
- StyleName = ParseState.TokenValue
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchStringQQ() then signal syntax; /* FontName */
- FontName = ParseState.TokenValue
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- call ParseTrace("StyleName '"StyleName"' specifies font '"FontName"'")
- call ParseTraceExit("CStyleSpec")
- return 1
-
-
- /* PStyleRegion := "PSTYLE" StyleName Num1 Num2 Num3 "{" CSTYLE "}";
- */
- PStyleRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("PSTYLE") then return 0
- call ParseTraceEntry("PStyleRegion")
- if ~MatchStringQQ() then signal syntax; /* StyleName */
- StyleName = ParseState.TokenValue
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- call ParseTrace("StyleName '"StyleName"'")
- if ~MatchOperator("{") then signal syntax
- if ~CStyleSpec() then signal syntax
- if ~MatchOperator("}") then signal syntax
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- if ~MatchNumber() then signal syntax;
- call ParseTraceExit("PStyleRegion")
- return 1
-
-
- /* SectionRegion := "SECT" SectNumber
- * "{" ExchgSection | SectionRegion | ParaSection "}";
- */
- SectionRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("SECT") then return 0
- call ParseTraceEntry("SectionRegion")
- if ~MatchNumber() then signal syntax; /* SectNumber */
- SectNumber = ParseState.TokenValue
- call ParseTrace("SectionNumber" SectNumber)
- do forever
- if ~MatchOperator("{") then leave
- if ~ExchgSection() ,
- then if ~SectionRegion() ,
- then if ~ParaSection() then signal syntax
- if ~MatchOperator("}") then signal syntax
- end
- call ParseTraceExit("SectionRegion: " || SectNumber)
- return 1
-
-
- /*
- * ExchgSection := "EXCHG" "{" ParaSection ... "}";
- */
- ExchgSection: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("EXCHG") then return 0
- call ParseTraceEntry("ExchgSection")
- do forever
- if ~MatchOperator("{") then leave
- if ~ParaSection() then signal syntax
- if ~MatchOperator("}") then signal syntax
- end
- call ParseTraceExit("ExchgSection")
- return 1
-
-
- /*
- * ParaSection := "PARA" ParaNumber BegString Num1 SecString
- * "{" TextRegion | MapleTextRegion | XPPMathRegion | XPPEditRegion |
- * HyperLinkRegion | InlinePlotRegion "}";
- */
- ParaSection: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("PARA") then return 0
- call ParseTraceEntry("ParagraphSection")
- if ~MatchNumber() then signal syntax /* ParaNumber */
- ParaNumber = ParseState.TokenValue
- if ~MatchStringQQ() then signal syntax /* BegString */
- BegString = ParseState.TokenValue
- if ~MatchNumber() then signal syntax /* Num1 */
- if ~MatchStringQQ() then signal syntax /* SecString */
- call ParseTrace("ParagraphSection" ParaNumber "starts with '"BegString"'")
-
- oldtextType=-1
- do forever
- if ~MatchOperator("{") then leave
- if TextRegion() then textType=0
- else if MapleTextRegion() then textType=1
- else if XPPMathRegion() then textType=2
- else if XPPEditRegion() then textType=0
- else if HyperLinkRegion() then textType=0
- else if InlinePlotRegion() then textType=2
- else signal syntax
- if ~MatchOperator("}") then signal syntax
-
- select
- when textType=0 then do /* Kommentar */
- if ExecuteState.CallMaple ,
- then do
- call ParseTrace("Inserting Comment Region")
- if textType ~= oldtextType then do
- "EndOfRegion"
- "NewText"
- end
- "Insert" ParseState.SemanticText
- call SendReturn()
- end
- else say "Comment Region contained text: <" ParseState.SemanticText ">"
- end
- when textType=1 then do
- if ExecuteState.CallMaple ,
- then do
- call ParseTrace("Inserting Input Region")
- if textType ~= oldtextType then do
- "EndOfRegion"
- "NewInput"
- end
- "Insert" ParseState.SemanticText
- call SendReturn()
- end
- else say "Input Region contained text: <" ParseState.SemanticText ">"
- end
- when textType=2 then do
- nop
- end
- end
- oldtextType=textType
- end
- call ParseTraceExit("ParagraphSection")
- return 1
-
-
- /*
- * MarkSection := "MARK" MarkText Number ;
- */
- MarkSection: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("MARK") then return 0
- call ParseTraceEntry("MarkSection")
- if ~MatchStringQQ() then signal syntax; /* MarkText */
- if ~MatchNumber() then signal syntax; /* Number */
- call ParseTraceExit("MarkSection")
- return 1
-
-
- /*
- * ViewOptsSection := "VIEWOPTS" Opt1 Opt2 Opt3 Opt4 Opt5 Opt6
- */
- ViewOptsSection: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("VIEWOPTS") then return 0
- call ParseTraceEntry("ViewOptsSection")
- if ~MatchNumber() then signal syntax; /* Opt1 */
- if ~MatchNumber() then signal syntax; /* Opt2 */
- if ~MatchNumber() then signal syntax; /* Opt3 */
- if ~MatchNumber() then signal syntax; /* Opt4 */
- if ~MatchNumber() then signal syntax; /* Opt5 */
- if ~MatchNumber() then signal syntax; /* Opt6 */
- call ParseTraceExit("ViewOptsSection")
- return 1
-
-
- /* FontRegion := "FONT" FontNumber FontString1 FontString2 FontString3
- * FontNumA FontSize1 FontFlags FontString4 FontSize4
- * "{" ColorSpec "}";
- */
- FontRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("FONT") then return 0
- call ParseTraceEntry("FontRegion")
- if ~MatchNumber() then signal syntax; /* FontNumber */
- FontNumber = ParseState.TokenValue
- if ~MatchStringQQ() then signal syntax /* FontString1 */
- FontString1 = ParseState.TokenValue
- if ~MatchStringQQ() then signal syntax /* FontString2 */
- FontString2 = ParseState.TokenValue
- if ~MatchStringQQ() then signal syntax /* FontString3 */
- FontString3 = ParseState.TokenValue
- if ~MatchNumber() then signal syntax; /* FontNumA */
- if ~MatchNumber() then signal syntax; /* FontSize1 */
- FontSize1 = ParseState.TokenValue
- if ~MatchNumber() then signal syntax; /* FontFlags */
-
- if ~MatchStringQQ() then signal syntax /* FontString4 */
- FontString4 = ParseState.TokenValue
- if ~MatchNumber() then signal syntax; /* FontSize4 */
- call ParseTrace("FontNumber" FontNumber "specifies fonts" FontString1 FontString2 FontString3 FontString4 "at size" FontSize1)
- if ~MatchOperator("{") then signal syntax
- if ~ColorSpec() then signal syntax
- if ~MatchOperator("}") then signal syntax
- call ParseTraceExit("FontRegion: " || FontNumber)
- return 1
-
-
- /* ColorSpec := "COLOR" ColorFlagsString ;
- */
- ColorSpec: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("COLOR") then return 0
- call ParseTraceEntry("ColorSpec")
- if ~MatchStringQQ() then signal syntax; /* ColorFlagsString */
- call ParseTraceExit("ColorSpec")
- return 1
-
-
- /*
- * RegionObject := "{" ScpRegion
- * | ComRegion
- * | InpRegion
- * | OutRegion
- * | AgrRegion
- * | CgrRegion
- * "}";
- */
- RegionObject: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchOperator("{") then return 0;
- call ParseTraceEntry("RegionObject")
-
- if ~ScpRegion() ,
- then if ~ComRegion() ,
- then if ~InpRegion() ,
- then if ~OutRegion() ,
- then if ~AgrRegion() ,
- then if ~CgrRegion() then signal syntax
-
- if ~MatchOperator("}") then signal syntax;
- call ParseTraceExit("RegionObject")
- return 1
-
-
- /*
- * ScpRegion := "SCP_R" RegionNumber RegionNumB RegionCount
- * RegionObject(s)... ;
- */
- ScpRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("SCP_R") then return 0
- call ParseTraceEntry("ScpRegion")
- if ~RegionNumber() then signal syntax; /* RegionNumber */
- ThisRegionNumber = ParseState.TokenValue
-
- if ~MatchNumber() then signal syntax; /* RegionNumB */
-
- if ~MatchNumber() then signal syntax; /* RegionCount */
- RegionCount = ParseState.TokenValue
- call ParseTrace("ScpRegion" ThisRegionNumber "has" RegionCount "subregions")
- do ii=0 by 1 for RegionCount
- call ParseTrace("Processing ScpRegion."ThisRegionNumber"."ii)
- if ~RegionObject() then signal syntax;
- end
- call ParseTraceExit("ScpRegion: "|| ThisRegionNumber)
- return 1
-
-
- /*
- * ComRegion := "COM_R" RegionNumber RegionNumB "{" TextRegion "}" ;
- */
- ComRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("COM_R") then return 0
- call ParseTraceEntry("ComRegion")
- if ~RegionNumber() then signal syntax; /* RegionNumber */
- ThisRegionNumber = ParseState.TokenValue
-
- if ~MatchNumber() then signal syntax; /* RegionNumB */
- if ~MatchOperator("{") then signal syntax;
- if ~TextRegion() then signal syntax;
-
- if ExecuteState.CallMaple ,
- then do
- call ParseTrace("Inserting Comment Region" ThisRegionNumber '0A'x"<" ParseState.SemanticText ">")
- "EndOfRegion"
- "NewText"
- "Insert" ParseState.SemanticText
- end
- else say "Comment Region" ThisRegionNumber "contained text:" '0A'x"<" ParseState.SemanticText ">"
-
- if ~MatchOperator("}") then signal syntax;
- call ParseTraceExit("ComRegion: "|| ThisRegionNumber)
- return 1
-
-
- /*
- * InpRegion := "INP_R" RegionNumber RegionNumB [ PromptString ]
- * "{" TextRegion "}" ;
- */
- InpRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("INP_R") then return 0
- call ParseTraceEntry("InpRegion")
- if ~RegionNumber() then signal syntax; /* RegionNumber */
- ThisRegionNumber = ParseState.TokenValue
-
- if ~MatchNumber() then signal syntax; /* RegionNumB */
- if MatchStringQQ() then nop /* PromptString (optional) */
- if ~MatchOperator("{") then signal syntax;
- if ~TextRegion() then signal syntax;
- if ~MatchOperator("}") then signal syntax;
-
-
- if ExecuteState.CallMaple ,
- then do
- call ParseTrace("Inserting Input Region" ThisRegionNumber '0A'x"<" ParseState.SemanticText ">")
- "EndOfRegion"
- "NewInput"
- "Insert" ParseState.SemanticText
- call SendReturn()
- end
- else say "Input Region" ThisRegionNumber "contained text:" '0A'x"<" ParseState.SemanticText ">"
- call ParseTraceExit("InpRegion: "|| ThisRegionNumber)
- return 1
-
-
- /* OutRegion := "OUT_R" RegionNumber RegionNumB DagSize
- * "{" [ DagRegion | TextRegion ]"}";
- */
- OutRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("OUT_R") then return 0
- call ParseTraceEntry("OutRegion")
- if ~RegionNumber() then signal syntax; /* RegionNumber */
- ThisRegionNumber = ParseState.TokenValue
- if ~MatchNumber() then signal syntax; /* RegionNumB */
- if ~MatchNumber() then signal syntax; /* DagSize */
-
- if ~MatchOperator("{") then signal syntax;
- if ~DagRegion()
- then if ~TextRegion() then signal syntax;
- if ~MatchOperator("}") then signal syntax;
- call ParseTraceExit("OutRegion: " || ThisRegionNumber)
- return 1
-
-
- /* DagRegion := "DAG" <anything but "}" or EOF> ;
- */
- DagRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("DAG") then return 0
- call ParseTraceEntry("DagRegion")
- call ParseTrace("Skipping Dag data")
- do until MatchOperator("}") | MatchEOF()
- call GetToken()
- end
- call UnGetToken()
- call ParseTrace("Dag data skipped")
- call ParseTraceExit("DagRegion")
- return 1
-
-
- /* CgrRegion := "CGR_R" RegionNumber DibSize
- * "{" DibRegion "}";
- */
- CgrRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("CGR_R") then return 0
- call ParseTraceEntry("CgrRegion")
- if ~RegionNumber() then signal syntax; /* RegionNumber */
- ThisRegionNumber = ParseState.TokenValue
-
- if ~MatchNumber() then signal syntax; /* DibSize */
-
- if ~MatchOperator("{") then signal syntax;
- if ~DibRegion() then signal syntax;
- if ~MatchOperator("}") then signal syntax;
- call ParseTraceExit("CgrRegion: " || ThisRegionNumber)
- return 1
-
-
- /* DibRegion := "DIB" DibNumA DibSize DigData> ;
- */
- DibRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("DIB") then return 0
- call ParseTraceEntry("DibRegion")
- if ~MatchNumber() then signal syntax /* DibNumA */
- if ~MatchNumber() then signal syntax /* DibSize */
- if ~DibData() then signal syntax /* DibData */
- call ParseTraceExit("DibRegion")
- return 1
-
-
- /* DibData := <anything but "}" or EOF>;
- */
- DibData: procedure expose WsIn LexState. ParseState. ExecuteState.
- call ParseTraceEntry("DibData")
- call ParseTrace("Skipping Dib data")
- do until ( (CurrentChar == "}") | (CurrentChar == '04'x) )
- CurrentChar = GetChar()
- end
- call UnGetChar()
- call GetToken() /* Sync GetToken & GetChar */
- call UnGetToken() /* Put the "}" back */
- call ParseTrace("Dib data skipped")
- call ParseTraceExit("DibData")
- return 1
-
-
- /* AgrRegion := "AGR_R" RegionNumber RegionNumB
- * StringList ;
- */
- AgrRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("AGR_R") then return 0
- call ParseTraceEntry("AgrRegion")
- if ~RegionNumber() then signal syntax; /* RegionNumber */
- ThisRegionNumber = ParseState.TokenValue
- if ~MatchNumber() then signal syntax; /* RegionNumB */
- if ~StringList() then signal syntax;
- call ParseTraceExit("AgrRegion: " || ThisRegionNumber)
- return 1
-
-
- /*
- * TextRegion := "TEXT" FontNumber TextSize TextString ;
- */
- TextRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("TEXT") then return 0
- call ParseTraceEntry("TextRegion")
- if ~MatchNumber() then signal syntax; /* FontNumber */
- if ~MatchNumber() then signal syntax; /* TextSize */
- if ~MatchStringQQ() then signal syntax; /* Quoted Text */
- ParseState.SemanticText = ParseState.TokenValue
- call ParseTraceExit("TextRegion")
- return 1
-
-
- /*
- * MapleTextRegion := "MPLTEXT" FontNumber ParaNumber TextSize TextString ;
- */
- MapleTextRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("MPLTEXT") then return 0
- call ParseTraceEntry("MapleTextRegion")
- if ~MatchNumber() then signal syntax; /* FontNumber */
- if ~MatchNumber() then signal syntax; /* ParaNumber */
- if ~MatchNumber() then signal syntax; /* TextSize */
- if ~MatchStringQQ() then signal syntax; /* Quoted Text */
- ParseState.SemanticText = ParseState.TokenValue
- call ParseTraceExit("MapleTextRegion")
- return 1
-
-
- /*
- * XPPMathRegion := "XPPMATH" TextSize TextString ;
- */
- XPPMathRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("XPPMATH") then return 0
- call ParseTraceEntry("XPPMathRegion")
- if ~MatchNumber() then signal syntax; /* TextSize */
- if ~MatchStringQQ() then signal syntax; /* Quoted Text */
- ParseState.SemanticText = ParseState.TokenValue
- call ParseTraceExit("XPPMathRegion")
- return 1
-
-
- /*
- * XPPEditRegion := "XPPEDIT" Num1 Num2 Text MathStuff;
- */
- XPPEditRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("XPPEDIT") then return 0
- call ParseTraceEntry("XPPEditRegion")
- if ~MatchNumber() then signal syntax; /* Num1 */
- if ~MatchNumber() then signal syntax; /* Num2 */
- if ~MatchStringQQ() then signal syntax; /* Quoted Text */
- ParseState.SemanticText = ParseState.TokenValue
- if ~MatchStringQQ() then signal syntax; /* MathStuff */
- call ParseTraceExit("XPPEditRegion")
- return 1
-
-
- /*
- * HyperLinkRegion := "HYPERLNK" LinkNum1 LinkText LinkNum2 LinkFile Text;
- */
- HyperLinkRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("HYPERLNK") then return 0
- call ParseTraceEntry("HyperLinkRegion")
- if ~MatchNumber() then signal syntax; /* LinkNum1 */
- if ~MatchStringQQ() then signal syntax; /* LinkText */
- ParseState.SemanticText = " _" || ParseState.TokenValue || "_ "
- if ~MatchNumber() then signal syntax; /* LinkNum2 */
- if ~MatchStringQQ() then signal syntax; /* LinkFile */
- if ~MatchStringQQ() then signal syntax; /* Text */
- call ParseTraceExit("HyperLinkRegion")
- return 1
-
-
- /*
- * InlinePlotRegion := "INLPLOT" PlotText Num1 .. Num44;
- */
- InlinePlotRegion: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchKeyWord("INLPLOT") then return 0
- call ParseTraceEntry("InlinePlotRegion")
- if ~MatchStringQQ() then signal syntax; /* PlotText */
- do ii=1 by 1 for 13
- if ~MatchNumber() then signal syntax; /* LinkNumX */
- end
- do ii=14 by 1 for 3
- if ~MatchReal() then signal syntax; /* LinkNumX */
- end
- do ii=17 by 1 for 29
- if ~MatchNumber() then signal syntax; /* LinkNumX */
- end
- call ParseTraceExit("InlinePlotRegion")
- return 1
-
-
- /* RegionNumber := Number ;
- */
- RegionNumber: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchNumber() then return 0
- call ParseTrace("Processing RegionNumber =" ParseState.TokenValue)
- return 1
-
-
- /* StringList := String
- * | String StringList;
- */
- StringList: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchStringQQ() then return 0;
- call ParseTraceEntry("StringList")
- do while MatchStringQQ();
- end
- call ParseTraceExit("StringList")
- return 1
-
-
- /* Match a specified operator
- * If not matched: Return FALSE (0)
- * Else GetToken, and Return TRUE (1)
- */
- MatchOperator: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- TargetOp = arg(1)
- if ParseState.TokenType ~== "/*OP*/" then return 0
- if ParseState.CurrentToken ~== TargetOp then return 0
- call GetToken()
-
- return 1 /* TRUE (1) means matched */
-
-
- /* Match a specified keyword
- * If not matched: Return FALSE (0)
- * Else GetToken, and Return TRUE (1)
- */
- MatchKeyWord: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- TargetKeyWord = arg(1)
- if ParseState.TokenType ~== "/*KEY*/" then return 0
- if ParseState.CurrentToken ~== TargetKeyWord then return 0
- call GetToken()
-
- return 1 /* TRUE (1) means matched */
-
-
- /* Match an identifier
- * If not matched: Return FALSE (0)
- * Else GetToken, and Return TRUE (1)
- */
- MatchIdentifier: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ParseState.TokenType ~== "/*KEY*/" then return 0
- ParseState.TokenValue = ParseState.CurrentToken
- call GetToken()
-
- return 1 /* TRUE (1) means matched */
-
-
- /* Match a number
- * If not matched: Return FALSE (0)
- * Else GetToken, and Return TRUE (1)
- * Value of number returned in ParseState.TokenValue
- */
- MatchNumber: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ParseState.TokenType ~== "/*NUM*/" then return 0
- ParseState.TokenValue = 0 + ParseState.CurrentToken
- call GetToken()
-
- return 1 /* TRUE (1) means matched */
-
-
- /* Match a real number
- * If not matched: Return FALSE (0)
- * Else GetToken, and Return TRUE (1)
- * Value of number returned in ParseState.TokenValue
- */
- MatchReal: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ~MatchNumber() then signal syntax;
- value = ParseState.TokenValue;
- if ~MatchOperator(".") then signal syntax;
- if ~MatchNumber() then signal syntax;
- fraction = ParseState.TokenValue;
- ParseState.TokenValue = value + fraction/1000000
-
- return 1 /* TRUE (1) means matched */
-
-
- /* Match a "string"
- * If not matched: Return FALSE (0)
- * Else GetToken, and Return TRUE (1)
- * Contents of string returned in ParseState.TokenValue
- */
- MatchStringQQ: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ParseState.TokenType ~== "/*STRQQ*/" then return 0
- ParseState.TokenValue = ParseState.CurrentToken
- call GetToken()
-
- return 1 /* TRUE (1) means matched */
-
-
- /* Match a 'string'
- * If not matched: Return FALSE (0)
- * Else GetToken, and Return TRUE (1)
- * Contents of string returned in ParseState.TokenValue
- */
- MatchStringQ: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ParseState.TokenType ~== "/*STRQ*/" then return 0
- ParseState.TokenValue = ParseState.CurrentToken
- call GetToken()
-
- return 1 /* TRUE (1) means matched */
-
-
- /* Match a `string`
- * If not matched: Return FALSE (0)
- * Else GetToken, and Return TRUE (1)
- * Contents of string returned in ParseState.TokenValue
- */
- MatchStringT: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ParseState.TokenType ~== "/*STRTIC*/" then return 0
- ParseState.TokenValue = ParseState.CurrentToken
- call GetToken()
-
- return 1 /* TRUE (1) means matched */
-
-
- /* Match EOF
- * If not matched: Return FALSE.
- * Else Return TRUE (1)
- */
- MatchEOF: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ParseState.TokenType ~== "/*EOF*/" then return 0
- ParseState.CurrentToken = "/*EOF*/"
- return 1 /* TRUE (1) means matched */
-
-
- /* Issue a token tracing message */
- TokenTrace: procedure expose LexState. ParseState. ExecuteState.
- if ParseState.TokenTrace ,
- then say right("",ParseState.Indent,'09'x)"GetToken Token=<"ParseState.CurrentToken"> Type =" ParseState.TokenType
- return
-
- /* Issue a parse trace entered message */
- ParseTrace: procedure expose LexState. ParseState. ExecuteState.
- if ParseState.ParseTrace then say right("",ParseState.Indent,'09'x)arg(1)
- return
-
-
- /* Issue a parse trace entered message */
- ParseTraceEntry: procedure expose LexState. ParseState. ExecuteState.
- if ParseState.ParseTrace ,
- then say right("",ParseState.Indent,'09'x)arg(1) "Entered"
- ParseState.Indent = ParseState.Indent + 1
- return
-
-
- /* Issue a parse trace exited message */
- ParseTraceExit: procedure expose LexState. ParseState. ExecuteState.
- ParseState.Indent = ParseState.Indent - 1
- if ParseState.ParseTrace ,
- then say right("",ParseState.Indent,'09'x)arg(1) "Exited"
- return
-
- /* Return next token from input stream, or '/*EOF*/' */
- GetToken: procedure expose WsIn LexState. ParseState. ExecuteState.
-
- if ParseState.UnGetQueue ~== "" ,
- then do
- ParseState.CurrentToken = ParseState.UnGetQueue
- ParseState.UnGetQueue = ""
- ParseState.TokenType = ParseState.UnGetTypeQueue
- ParseState.UnGetTypeQueue = ""
- call TokenTrace()
- return
- end
-
- CurrentChar = GetChar()
- do while verify(CurrentChar,'090A0B0C0D20'x) = 0
- CurrentChar = GetChar()
- end
- if CurrentChar = '04'x ,
- then do
- ParseState.CurrentToken = "/*EOF*/"
- ParseState.TokenType = "/*EOF*/"
- call TokenTrace()
- return
- end
-
- select;
- when CurrentChar == '"' ,
- then do
- ParseState.CurrentToken = ""
- ParseState.TokenType = "/*STRQQ*/"
-
- CurrentChar = GetChar()
- do while CurrentChar ~== '"' & CurrentChar ~== '04'x
- if CurrentChar == "\" ,
- then do
- CurrentChar = GetChar()
- select
- when CurrentChar == '04'x ,
- then say "3 Digit octal string truncated by EOF"
- when CurrentChar == '+' ,
- then CurrentChar = ""
- when CurrentChar == 'n' ,
- then CurrentChar = '0a'x
- when verify(CurrentChar,"01234567") = 0 ,
- then do
- CharNumber = CurrentChar
- do i=1 to 2
- CurrentChar = GetChar()
- select;
- when CurrentChar == '04'x ,
- then say "3 Digit octal string truncated by EOF"
- when CurrentChar == '"' ,
- then say '3 Digit octal string truncated by "'
- otherwise
- if verify(CurrentChar,"01234567") ~= 0 ,
- then say "3 Digit octal string truncated by" CurrentChar
- else CharNumber = 8 * CharNumber + CurrentChar
- end
- end
- CurrentChar = d2c(CharNumber)
- end
- otherwise
- nop;
- end
- end
- else if CurrentChar == '0d'x ,
- then do
- CurrentChar = ""
- end
- ParseState.CurrentToken = ParseState.CurrentToken || CurrentChar
- CurrentChar = GetChar()
- end
- if CurrentChar == '04'x ,
- then say 'Missing " from string (EOF hit).'
- call TokenTrace()
- return
- end
-
- when CurrentChar == "`" ,
- then do
- ParseState.CurrentToken = ""
- ParseState.TokenType = "/*STRTIC*/"
-
- CurrentChar = GetChar()
- do while CurrentChar ~== "`" & CurrentChar ~== '04'x
- ParseState.CurrentToken = ParseState.CurrentToken || CurrentChar
- CurrentChar = GetChar()
- end
- if CurrentChar == '04'x ,
- then say "Missing ` from string (EOF hit)."
- call TokenTrace()
- return
- end
-
- when verify(CurrentChar,"ABCDEFGHIJKLMNOPQRSTUVWXYZ_") = 0 ,
- then do
- ParseState.CurrentToken = CurrentChar
- ParseState.TokenType = "/*KEY*/"
-
- CurrentChar = GetChar()
- do while verify(CurrentChar,"ABCDEFGHIJKLMNOPQRSTUVWXYZ_") = 0
- ParseState.CurrentToken = ParseState.CurrentToken || CurrentChar
- CurrentChar = GetChar()
- end
- call UnGetChar(CurrentChar)
- call TokenTrace()
- return
- end;
-
- when verify(CurrentChar,"-0123456789") = 0 ,
- then do
- ParseState.CurrentToken = CurrentChar
- ParseState.TokenType = "/*NUM*/"
-
- CurrentChar = GetChar()
- do while verify(CurrentChar,"0123456789") = 0
- if CurrentChar == '04'x ,
- then return ParseState.CurrentToken
- ParseState.CurrentToken = ParseState.CurrentToken || CurrentChar
- CurrentChar = GetChar()
- end
- call UnGetChar(CurrentChar)
- call TokenTrace()
- return
- end;
-
- otherwise
- do
- ParseState.CurrentToken = CurrentChar
- ParseState.TokenType = "/*OP*/"
- call TokenTrace()
- return
- end
- end;
-
- ParseState.CurrentToken ="/*ERROR*/"
- ParseState.TokenType ="/*ERROR*/"
- call TokenTrace()
- return
-
-
- /* Push back a single token onto the UnGetTokenQueue */
- UnGetToken: procedure expose ParseState.
- if ParseState.TokenTrace ,
- then say right("",ParseState.Indent,'09'x)"UnGetToken=<"ParseState.CurrentToken"> Type ="ParseState.TokenType
- ParseState.UnGetQueue = ParseState.CurrentToken
- ParseState.UnGetTypeQueue = ParseState.TokenType
- return
-
-
- /* Returns a single character at every call;
- * At EOF, it then returns the single char EOT ('04'x) */
- GetChar: procedure expose WsIn LexState.
-
- if length(LexState.UnGetQueue) > 0 ,
- then do
- ReturnChar = substr(LexState.UnGetQueue,1,1)
- LexState.UnGetQueue = delstr(LexState.UnGetQueue,1,1)
- return ReturnChar
- end
-
- if LexState.CurrentLine == "" ,
- | LexState.CurrentCol > length(LexState.CurrentLine) ,
- | LexState.CurrentCol <= 0,
- then do
- if eof(WsIn) ,
- then return '04'x
-
- do until LexState.CurrentLine ~== ""
- LexState.CurrentLine = readln(WsIn)
- LexState.LineNumber = LexState.LineNumber + 1
- if eof(WsIn) ,
- then return '04'x
- if LexState.List ,
- then say right(LexState.LineNumber,5," ") Lexstate.CurrentLine
- end
- LexState.CurrentCol = 1
- end
-
- CurrentChar = substr(LexState.CurrentLine, LexState.CurrentCol, 1)
- LexState.CurrentCol = LexState.CurrentCol + 1
- return CurrentChar
-
-
- /* Push back a single character onto the LexState.UnGetQueue */
- UnGetChar: procedure expose LexState.
- LexState.UnGetQueue = arg(1) || LexState.UnGetQueue
- return
-
-
- /* Wait until Maple is idle,
- * then send a return to force it to start executing. */
- SendReturn: procedure expose ExecuteState.
- if ~ExecuteState.Async ,
- then do
- do until MapleRC = 0
- "GetMapleStatus"
- MapleRC = RC
- address command "wait 3 secs"
- end
- end
- "SendReturn"
- return
-